package cn.swust.designpatternlearningplatform.service.impl;

import cn.swust.designpatternlearningplatform.common.Result.PageInfo;
import cn.swust.designpatternlearningplatform.common.utils.OrikaMapperUtil;
import cn.swust.designpatternlearningplatform.dao.*;
import cn.swust.designpatternlearningplatform.domain.bo.StudentTopicTypeBo;
import cn.swust.designpatternlearningplatform.domain.dto.KnowledgePointDto;
import cn.swust.designpatternlearningplatform.domain.dto.TopicOptionDto;
import cn.swust.designpatternlearningplatform.domain.dto.TopicShieldDto;
import cn.swust.designpatternlearningplatform.domain.entity.*;
import cn.swust.designpatternlearningplatform.domain.enums.TopicUpdateTypeEnum;
import cn.swust.designpatternlearningplatform.service.TopicShieldService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TopicShieldServiceImpl implements TopicShieldService {
    @Resource
    private TopicDao topicDao;
    @Resource
    private TopicUpdateDao topicUpdateDao;
    @Resource
    private TopicKnowledgePointDao topicKnowledgePointDao;
    @Resource
    private TopicKnowledgeCorrelationDao topicKnowledgeCorrelationDao;
    @Resource
    private TopicOptionDao topicOptionDao;

    /**
     * 增加屏蔽题
     *
     * @return void
     * @author Tang
     * @date 2023/4/16 0:46
     **/
    @Override
    public void addTopicShield(String studentNumber, List<Integer> topicIds) {
        TopicUpdate topicUpdate = new TopicUpdate();
        //查询所要屏蔽题目的信息
        Map<Integer, Topic> collect = topicDao.selectTopicsByIds(topicIds)
                .stream()
                .collect(Collectors.toMap(Topic::getTopicId, i -> i));
        for (Integer id : topicIds) {
            topicUpdate.setStudentNumber(studentNumber);
            topicUpdate.setTopicId(id);
            topicUpdate.setUpdateType(TopicUpdateTypeEnum.SHIELD.getTypeName());
            topicUpdate.setUpdateTime(Timestamp.from(Instant.now()));
            //已经屏蔽
            if (topicUpdateDao.selectTopicUpdate(topicUpdate) != null) {
                continue;
            }
            topicUpdate.setTopicType(collect.get(id).getTopicType());
            //未屏蔽
            topicUpdateDao.insertTopicUpdate(topicUpdate);
        }
    }

    /**
     * 取消屏蔽题
     *
     * @param studentTopicTypeBo
     * @return void
     * @author Tang
     * @date 2023/4/16 0:46
     **/
    @Override
    public void cancelTopicShield(StudentTopicTypeBo studentTopicTypeBo) {
        for (Integer id : studentTopicTypeBo.getTopicId()) {
            TopicUpdate topicUpdate = new TopicUpdate();
            topicUpdate.setStudentNumber(studentTopicTypeBo.getStudentNumber());
            topicUpdate.setTopicId(id);
            topicUpdate.setUpdateType(studentTopicTypeBo.getTopicType());
            topicUpdateDao.deleteTopicUpdate(topicUpdate);
        }
    }

    /**
     * 分页获取屏蔽题目
     *
     * @param studentTopicTypeBo
     * @return java.util.List<cn.swust.designpatternlearningplatform.domain.entity.Topic>
     * @author Tang
     * @date 2023/4/21 14:39
     **/
    @Override
    public PageInfo<TopicShieldDto> getTopicShieldList(StudentTopicTypeBo studentTopicTypeBo) {
        TopicUpdate topicUpdate = new TopicUpdate();
        BeanUtils.copyProperties(studentTopicTypeBo, topicUpdate, "topicId");
        Integer current = studentTopicTypeBo.getCurrent();
        Integer size = studentTopicTypeBo.getSize();
        Integer total = topicUpdateDao.selectTopicUpdateByStudentTotal(topicUpdate);
        //分页查询屏蔽题目
        List<TopicUpdate> topicUpdates = topicUpdateDao
                .selectTopicUpdateByStudent(topicUpdate, (current - 1) * size, size);
        //批量查询题目信息
        List<Integer> topicIds = topicUpdates
                .stream()
                .map(TopicUpdate::getTopicId).collect(Collectors.toList());
        Map<Integer, Topic> topicMap = topicDao.selectTopicsByIds(topicIds)
                .stream()
                .collect(Collectors.toMap(Topic::getTopicId, i -> i));
        //查询收藏情况
        topicUpdate.setUpdateType(TopicUpdateTypeEnum.COLLECT.getTypeName());
        Set<Integer> isCollect = new HashSet<>(topicUpdateDao.selectAllByTopicType(topicUpdate));
        //查询题目选项
        List<TopicOption> topicOptions = topicOptionDao.getByTopicIds(new HashSet<>(topicIds));
        List<TopicOptionDto> topicOptionDtos = OrikaMapperUtil.INSTANCE.mapAsList(TopicOptionDto.class, topicOptions);
        Map<Integer, List<TopicOptionDto>> topicOptionDtoMap = topicOptionDtos.stream()
                .collect(Collectors.groupingBy(TopicOptionDto::getTopicId));
        //查询知识点
        List<TopicKnowledgeCorrelation> topicKnowledgeCorrelations = topicKnowledgeCorrelationDao.selectPointsByTopicIds(topicIds);
        Map<Integer, Set<Integer>> topicIdWithPointIdMap = topicKnowledgeCorrelations.stream()
                .collect(Collectors.groupingBy(TopicKnowledgeCorrelation::getTopicId, Collectors.mapping(TopicKnowledgeCorrelation::getPointId, Collectors.toSet())));
        Set<Integer> pointIds = topicKnowledgeCorrelations.stream().map(TopicKnowledgeCorrelation::getPointId).collect(Collectors.toSet());
        List<KnowledgePoint> knowledgePoints = topicKnowledgePointDao.selectByPointIds(pointIds);
        List<KnowledgePointDto> knowledgePointDtoList = OrikaMapperUtil.INSTANCE.mapAsList(KnowledgePointDto.class, knowledgePoints);
        Map<Integer, KnowledgePointDto> knowledgePointDtoMap = knowledgePointDtoList.stream().collect(Collectors.toMap(KnowledgePointDto::getPointId, kp -> kp));

        //封装屏蔽题对象
        List<TopicShieldDto> topicShieldDtos = topicUpdates
                .stream().map(i -> {
                    TopicShieldDto topicShieldDto = new TopicShieldDto();
                    if (i == null) {
                        return null;
                    }
                    //屏蔽信息
                    BeanUtils.copyProperties(i, topicShieldDto);
                    //题目信息
                    Topic topic = topicMap.get(i.getTopicId());
                    if (topic == null) {
                        return null;
                    }
                    BeanUtils.copyProperties(topic, topicShieldDto);
                    //题目难度
                    topicShieldDto.setTopicDifficulty(topic.getTopicDifficulty());
                    //是否收藏
                    topicShieldDto.setIsCollect(isCollect.contains(i.getTopicId()));
                    //设置题目知识点
                    List<KnowledgePointDto> myKnowledgePoints = topicIdWithPointIdMap
                            .getOrDefault(i.getTopicId(), new HashSet<>())
                            .stream().map(knowledgePointDtoMap::get)
                            .collect(Collectors.toList());
                    topicShieldDto.setPoints(myKnowledgePoints);
                    //设置题目选项
                    topicShieldDto.setTopicOptionDtos(topicOptionDtoMap.get(i.getTopicId()));
                    return topicShieldDto;
                }).filter(Objects::nonNull).collect(Collectors.toList());
        return new PageInfo<>(total, current, size, topicShieldDtos);
    }

    /**
     * 返回用户某个题型的数量
     *
     * @param studentTopicTypeBo
     * @return java.lang.Integer
     * @author Tang
     * @date 2023/4/19 21:30
     **/
    @Override
    public Integer totalTopicShield(StudentTopicTypeBo studentTopicTypeBo) {
        TopicUpdate topicUpdate = new TopicUpdate();
        topicUpdate.setUpdateType(studentTopicTypeBo.getTopicType());
        topicUpdate.setStudentNumber(studentTopicTypeBo.getStudentNumber());
        return topicUpdateDao.countTopicUpdateByStudent(topicUpdate);
    }
}


